package net.yxsoft.service;

import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import net.yxsoft.kit.RemoteCommandKit;
import net.yxsoft.service.common.BaseService;
import org.apache.commons.io.FileUtils;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import rapid.core.TResult;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ChianPackAgeService extends BaseService {

    private static final String path=PathKit.getWebRootPath() +"/files/chianpackage";//文件根路径;
    private static long monitorPort=20001;//监控端口


    public static final ChianPackAgeService INSTANCE= new ChianPackAgeService();

    public TResult CreatePackageFolder(String chainId, String orgIds,String cid,String appPath) throws IOException {
        //监控端口
        monitorPort=20001;

        String filesPath=path+"/"+ chainId;
        //创建父文件夹
        File pathFile = new File(filesPath);
        //判断⽂件夹是否存在
        if (!pathFile.exists()) {
            //如果⽂件夹不存在，则创建新的的⽂件夹
            pathFile.mkdirs();
        }else {
            //保证每次都是最新的
            FileUtils.deleteDirectory(pathFile);//删除之前创建的链目录
            pathFile.mkdirs();
        }
        //1.准备好基础运行脚本无则新增
        CreateBaseFile(filesPath);

        String[] orgIdArr = orgIds.split(",");
        List orgNodesList = new ArrayList<>();//区块链父节点目录存储集合
        for (String orgId:orgIdArr) {
            Record record = Db.findFirst("SELECT * FROM cmb_org_node WHERE org_id=?", orgId);
            if(record==null){
                continue;
            }

            //2.创建区块链部署父文件夹目录（根）
            String parPath = record.getStr("org_id") + "-" + record.getStr("node_name");
            orgNodesList.add(parPath);
            String usePath = filesPath + "/"+parPath;
            //创建父文件夹
            File file = new File(usePath);
            //判断⽂件夹是否存在
            if (!file.exists()) {
                //如果⽂件夹不存在，则创建新的的⽂件夹
                file.mkdirs();
            }
            //3.准备好基础运行文件夹
            CreateBaseFolder(usePath,record.getStr("org_id"),record.getStr("node_name"));
            //4.替换基础运行文件夹中参数

            //生成config下工作目录
            String workPath = usePath + "/config/" + record.getStr("org_id");
            //创建工作文件夹
            File workFolder = new File(workPath);
            //判断工作文件夹是否存在
            workFolder.mkdirs();
            //创建工作目录下基础运行文件夹
            CreateCertsFolder(chainId,orgId,workPath);


            Record node = Db.findFirst("SELECT DISTINCT cert_type,node_name FROM cmb_cert WHERE org_id =? and cert_type in (4,5)",orgId);
            String nodeName = node.getStr("node_name");
            //创建工作目录下chainmaker.yml文件
            CreateChainmakerYml(chainId,orgId,record.getStr("org_id"),nodeName,workPath);
            monitorPort++;//端口ip+1

            //创建工作目录下bc1.yml
            String chainConfigPath = workPath + "/" + "chainconfig";
            //创建chainConfig文件夹
            File chainConfigFolder = new File(chainConfigPath);
            chainConfigFolder.mkdirs();
            CreateBcYml(chainId,orgId,record.getStr("org_id"),chainConfigPath);


            // 创建工作目录log.yml文件
            java.nio.file.Path sourcePath = Paths.get(PathKit.getRootClassPath()+"/chainPackage/config/", "log.yml");
            java.nio.file.Path targetPath = Paths.get(workPath, "log.yml");
            try {
                Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        //生成zip压缩包
        //compressFolderToZip(filesPath, filesPath, "chainmaker.zip");
        //添加--mode=go+rx 给里面的文件加上执行权限
        exeShell("tar -czvf "+path+"/chainmaker-"+chainId+".tar.gz  --mode=go+rx -C "+filesPath +" .");
        //上传到远程节点服务器
        packAgeUploadToRemote(cid,"chainmaker-"+chainId+".tar.gz",path+"/chainmaker-"+chainId+".tar.gz",appPath);
        //上传镜像文件到远程节点服务器,并且执行镜像sh脚本
        imgUploadToRemote(cid,appPath);
        //启动区块链节点
        startChianNodes(cid,appPath,orgNodesList);

        return TResult.success().set("msg", "执行成功！");
    }

    /**
     * 区块链虚拟化部署
    * */
    public TResult packageChainmakerVm(String chainId, String orgId,String cid,String appPath) throws IOException {
        //监控端口
        monitorPort=20001;
        String parPath = "wx-org4.chainmaker.org";
        //虚拟化父节点
        String filesPath=path+"/"+ chainId+"-vm";
        //创建父文件夹
        File pathFile = new File(filesPath);
        //判断⽂件夹是否存在
        if (!pathFile.exists()) {
            //如果⽂件夹不存在，则创建新的的⽂件夹
            pathFile.mkdirs();
        }else {
            //保证每次都是最新的
            FileUtils.deleteDirectory(pathFile);//删除之前创建的链目录
            pathFile.mkdirs();
        }
        //1.准备好基础虚拟化运行脚本无则新增
        CreateBaseVmFile(filesPath);

        List orgNodesList = new ArrayList<>();//区块链父节点目录存储集合
            Record record = Db.findFirst("SELECT * FROM cmb_org_node WHERE org_id=?", orgId);
            if(record==null){
                return TResult.fail("无此节点信息！");
            }

            //3.准备好基础运行文件夹
             CreateBaseVmFolder(filesPath,record.getStr("org_id"),record.getStr("node_name"));
            //生成config下工作目录
            String workPath = filesPath + "/config/"+parPath;
            //创建工作文件夹
            File workFolder = new File(workPath);
            //判断工作文件夹是否存在
            workFolder.mkdirs();
            //创建工作目录下基础运行文件夹
            CreateCertsFolder(chainId,orgId,workPath);

            Record node = Db.findFirst("SELECT DISTINCT cert_type,node_name FROM cmb_cert WHERE org_id =? and cert_type in (4,5)",orgId);
            String nodeName = node.getStr("node_name");
            //创建工作目录下chainmaker.yml文件
            CreateChainmakerYml(chainId,orgId,parPath,nodeName,workPath);
            monitorPort++;//端口ip+1

            //创建工作目录下bc1.yml
            String chainConfigPath = workPath + "/" + "chainconfig";
            //创建chainConfig文件夹
            File chainConfigFolder = new File(chainConfigPath);
            chainConfigFolder.mkdirs();
            CreateBcYml(chainId,orgId,parPath,chainConfigPath);


            // 创建工作目录log.yml文件
            java.nio.file.Path sourcePath = Paths.get(PathKit.getRootClassPath()+"/chainPackage/config/", "log.yml");
            java.nio.file.Path targetPath = Paths.get(workPath, "log.yml");
            try {
                Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                e.printStackTrace();
            }



        //添加--mode=go+rx 给里面的文件加上执行权限
        exeShell("tar -czvf "+path+"/chainmaker-"+chainId+"-vm.tar.gz  --mode=go+rx -C "+filesPath +" .");
        //上传到远程节点服务器
        packAgeUploadToRemote(cid,"chainmaker-"+chainId+"-vm.tar.gz",path+"/chainmaker-"+chainId+"-vm.tar.gz",appPath);
        //上传镜像文件到远程节点服务器,并且执行镜像sh脚本
        imgUploadToRemote(cid,appPath);
        //启动区块链节点
        //startChianNodes(cid,appPath,orgNodesList);

        return TResult.success().set("msg", "执行成功！");
    }




    /**
     * Java执行shell命令
     * */
    public void exeShell(String exec){
        try {
            // 执行ls命令
            Process process = Runtime.getRuntime().exec(exec);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 文件上传至目标节点
     * */
    public static void packAgeUploadToRemote(String cid,String fileName,String basePath,String appPath){
        Record record = Db.findFirst("select * from fn_form_data where conflict_id= ?",cid);
        String host = record.getStr("ATTRIB_07");//应用IP地址
        String port = record.getStr("ATTRIB_08");//应用端口
        String username = record.getStr("ATTRIB_31");//应用账号
        String password = record.getStr("ATTRIB_32");//应用密码
        try {
            RemoteCommandKit.remoteFileUploader(host,port,username,password,fileName,basePath,appPath);
            //解压文件夹
            String[] tarCommands = { "cd "+appPath+" && tar -xzvf "+fileName };
            //使用execRemoteCommandByResponse才能执行成功
            RemoteCommandKit.execRemoteCommandByResponse(host,port,username,password,tarCommands);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传镜像文件到指定目录，同时上传sh执行文件
     * */
    public static void imgUploadToRemote(String cid,String appPath){
        Record record = Db.findFirst("select * from fn_form_data where conflict_id= ?",cid);
        String host = record.getStr("ATTRIB_07");//应用IP地址
        String port = record.getStr("ATTRIB_08");//应用端口
        String username = record.getStr("ATTRIB_31");//应用账号
        String password = record.getStr("ATTRIB_32");//应用密码
        String basePath = PathKit.getRootClassPath() + "/img";
        String[] imgFiles = {"chainmaker-vm-engine-v2.3.2.img","chainmaker-vm-engine-v2.3.2.sh"};
        for (String imgFile:imgFiles) {
            try {
                RemoteCommandKit.remoteFileUploader(host,port,username,password,imgFile,basePath+"/"+imgFile,appPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        String[] imgShFiles={"chainmaker-vm-engine-v2.3.2.sh"};
        for (String imgShFile:imgShFiles) {
            try {
                //执行镜像文件
                String[] tarCommands = { "cd "+appPath+" && sh "+imgShFile };
                //使用execRemoteCommandByResponse才能执行成功
                RemoteCommandKit.execRemoteCommandByResponse(host,port,username,password,tarCommands);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 上传镜像文件到指定目录，同时上传sh执行文件
     * */
    public static void imgVmUploadToRemote(String cid,String appPath){
        Record record = Db.findFirst("select * from fn_form_data where conflict_id= ?",cid);
        String host = record.getStr("ATTRIB_07");//应用IP地址
        String port = record.getStr("ATTRIB_08");//应用端口
        String username = record.getStr("ATTRIB_31");//应用账号
        String password = record.getStr("ATTRIB_32");//应用密码
        String basePath = PathKit.getRootClassPath() + "/img";
        String[] imgFiles = {"chainmaker-vm-engine-v2.3.2.img","chainmaker.img","docker-compose.yml","start.sh"};
        for (String imgFile:imgFiles) {
            try {
                RemoteCommandKit.remoteFileUploader(host,port,username,password,imgFile,basePath+"/"+imgFile,appPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        String[] imgShFiles={"chainmaker-vm-engine-v2.3.2.sh","start.sh"};
        for (String imgShFile:imgShFiles) {
            try {
                //执行镜像文件
                String[] tarCommands = { "cd "+appPath+" && sh "+imgShFile };
                //使用execRemoteCommandByResponse才能执行成功
                RemoteCommandKit.execRemoteCommandByResponse(host,port,username,password,tarCommands);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 启动区块链目标节点
     * @param cid 应用单元Cid
     * @param appPath 节点服务器部署路径地址
     * @param nodesParPath 节点父目录
     * */
    public static void startChianNodes(String cid,String appPath,List<String> nodesParPath){
        Record record = Db.findFirst("select * from fn_form_data where conflict_id= ?",cid);
        String host = record.getStr("ATTRIB_07");//应用IP地址
        String port = record.getStr("ATTRIB_08");//应用端口
        String username = record.getStr("ATTRIB_31");//应用账号
        String password = record.getStr("ATTRIB_32");//应用密码
        for (String nodePath:nodesParPath) {
            try {
                //启动节点
                String[] startCommands = { "cd "+appPath+"/"+nodePath+"/bin && ./restart.sh " };
                RemoteCommandKit.execRemoteCommand(host,port,username,password,startCommands);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 创建基础运行文件
     * */
    public static void CreateBaseFile(String path){
            String[] filesToCopy = {"chainmaker", "quick_stop.sh", "start.sh","cmc"};
            String sourceFolder = PathKit.getRootClassPath()+"/chainPackage/";
            for (String fileName : filesToCopy) {
                try {
                    java.nio.file.Path sourcePath = Paths.get(sourceFolder, fileName);
                    java.nio.file.Path targetPath = Paths.get(path, fileName);
                    if (!Files.exists(targetPath)) {
                        Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    }

    /**
     * 创建基础运行文件
     * */
    public static void CreateBaseVmFile(String path){
        String[] filesToCopy = {"build.sh", "docker-compose.yml", "Dockerfile","start.sh","cmc"};
        String sourceFolder = PathKit.getRootClassPath()+"/chainmaker-vm/";
        for (String fileName : filesToCopy) {
            try {
                java.nio.file.Path sourcePath = Paths.get(sourceFolder, fileName);
                java.nio.file.Path targetPath = Paths.get(path, fileName);
                if (!Files.exists(targetPath)) {
                    Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 创建基础运行目录
     * */
    public static void CreateBaseFolder(String path,String orgId,String nodeName){
        try {
            String[] filesToCopy = {"bin", "lib"};
            String sourceFolder = PathKit.getRootClassPath()+"/chainPackage/";
            for (String fileName : filesToCopy) {
                File srcDir = new File(sourceFolder+fileName);
                File destDir = new File(path+"/"+fileName);
                FileUtils.copyDirectory(srcDir, destDir);
            }
            //将复制后的bin文件夹下sh文件参数替换
            //替换docker_start.sh中orgId和orgName中的值
            ReplaceShParams(path+"/bin/docker_start.sh","orgId",orgId);
            ReplaceShParams(path+"/bin/docker_start.sh","nodeName",nodeName);
            //替换stop.sh中orgId中的值
            ReplaceShParams(path+"/bin/stop.sh","orgId",orgId);
            //替换restart.sh中orgId中的值
            ReplaceShParams(path+"/bin/restart.sh","orgId",orgId);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建基础运行目录
     * */
    public static void CreateBaseVmFolder(String path,String orgId,String nodeName){
        try {
            String[] filesToCopy = {"bin", "lib"};
            String sourceFolder = PathKit.getRootClassPath()+"/chainmaker-vm/";
            for (String fileName : filesToCopy) {
                File srcDir = new File(sourceFolder+fileName);
                File destDir = new File(path+"/"+fileName);
                FileUtils.copyDirectory(srcDir, destDir);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * sh替换参数功能
     * */
    public static void  ReplaceShParams(String shPath,String replace,String target){
        try {
            // 读取sh文件内容
            File file = new File(shPath);
            BufferedReader reader = new BufferedReader(new FileReader(file));
            StringBuilder contentBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                // 使用正则表达式替换参数，同时保留原有结构
                String modifiedLine = line.replaceAll(replace, target);
                contentBuilder.append(modifiedLine).append("\n");
            }
            String newContent = contentBuilder.toString();
            reader.close();
            // 写入替换后的内容到同一个sh文件中
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            writer.write(newContent);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void CreateCertsFolder(String chainId,String orgId,String workPath){
        String usePath = workPath + "/certs";
        //创建certs⽂件夹⽬录
        File file = new File(usePath);
        //判断⽂件夹是否存在
        if (!file.exists()) {
            //如果⽂件夹不存在，则创建新的的⽂件夹
            file.mkdirs();
        }
        //生成certs下ca文件夹及证书
        CreateCaFolder(chainId,usePath);
        //生成certs下node文件夹及证书
        CreateNodeFolder(orgId,usePath);
        //生成certs下user文件夹及证书
        CreateUserFolder(orgId,usePath);
    }

    //创建certs下ca文件夹
    public static void CreateCaFolder(String chainId,String basePath){
        String usePath = basePath + "/ca";
        //创建certs下ca文件夹
        File file = new File(usePath);
        if (!file.exists()) {
            //如果⽂件夹不存在，则创建新的的⽂件夹
            file.mkdirs();
        }
        List<Record> records = Db.find("SELECT org_id AS orgId FROM cmb_chain_org_node WHERE chain_id= ?",chainId);
        for (Record record:records) {
            File jdFile = new File(usePath+"/"+record.getStr("orgId"));
            jdFile.mkdirs();
            //新建ca.crt证书
            Record certRecord = Db.findFirst("SELECT cert FROM cmb_cert WHERE cert_type='1' and org_id=?", record.getStr("orgId"));
            if(certRecord!=null){
                CreateCertsFile("ca.crt",usePath+"/"+record.getStr("orgId"),certRecord.getStr("cert"));
            }
        }

    }

    //创建certs下node文件夹
    public static void CreateNodeFolder(String orgId,String basePath){
        String usePath = basePath + "/node";
        //创建certs下node文件夹
        File file = new File(usePath);
        if (!file.exists()) {
            //如果⽂件夹不存在，则创建新的的⽂件夹
            file.mkdirs();
        }
        //通过证书角色获取node点（4,5类型是node的证书）const (ORG_CA= 1;ADMIN=2;CLIENT=3;CONSENSUS=4;COMMON=5;LIGHT=6)
        List<Record> records = Db.find("SELECT DISTINCT cert_type,node_name FROM cmb_cert WHERE org_id =? and cert_type in (4,5)",orgId);
        for (Record record:records) {
            File node = new File(usePath+"/"+record.getStr("node_name"));//创建certs下node文件夹下consensus文件夹
            node.mkdirs();
            CreateCertsCommonFile(record.getStr("node_name"),usePath+"/"+record.getStr("node_name"),orgId,record.getStr("cert_type"));
            Record cons = Db.findFirst("SELECT node_id FROM cmb_org_node WHERE org_id=?",orgId);
            if(cons!=null){
                CreateCertsFile(record.getStr("node_name")+".nodeid",usePath+"/"+record.getStr("node_name"),cons.getStr("node_id"));
            }
        }
    }


    //创建certs下user文件夹
    public static void CreateUserFolder(String orgId,String basePath){
        String usePath = basePath + "/user";
        //创建certs下node文件夹
        File file = new File(usePath);
        if (!file.exists()) {
            //如果⽂件夹不存在，则创建新的的⽂件夹
            file.mkdirs();
        }
        //通过证书角色获取node点（4,5类型是node的证书）const (ORG_CA= 1;ADMIN=2;CLIENT=3;CONSENSUS=4;COMMON=5;LIGHT=6)
        List<Record> records = Db.find("SELECT DISTINCT cert_type,cert_user_name FROM cmb_cert WHERE org_id =? and cert_type in (2,3,6)",orgId);
        for (Record record:records) {
            //通过证书角色创建文件夹
            File user = new File(usePath+"/"+record.getStr("cert_user_name"));//创建certs下user文件夹下
            user.mkdirs();
            CreateCertsCommonFile(record.getStr("cert_user_name"),usePath+"/"+record.getStr("cert_user_name"),orgId,record.getStr("cert_type"));
        }
    }


    //创建证书
    public static void CreateCertsFile(String name,String path,String content){
        try {
            // 创建一个File对象，即新建一个文件
            File file = new File(path+"/"+name);
            // 设置文件权限为可读写
            file.setReadable(true);
            file.setWritable(true);
            // 使用FileWriter类将内容写入文件
            FileWriter writer = new FileWriter(file);
            writer.write(content);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //创建通用证书
    public static void CreateCertsCommonFile(String name,String path,String orgId,String certType){
        //通过证书角色创建文件夹
        List<Record> adminRecord = Db.find("SELECT cert,private_key,cert_use FROM cmb_cert WHERE cert_type=? and org_id=?", certType, orgId);
        for (Record ad:adminRecord) {
            if("0".equals(ad.getStr("cert_use"))){
                CreateCertsFile(name+".sign.crt",path,ad.getStr("cert"));
                CreateCertsFile(name+".sign.key",path,ad.getStr("private_key"));
            }else if("1".equals(ad.getStr("cert_use"))){
                CreateCertsFile(name+".tls.crt",path,ad.getStr("cert"));
                CreateCertsFile(name+".tls.key",path,ad.getStr("private_key"));
            }
        }
    }



    /**
     * 创建Chainmaker.yml文件
     * */
    public static void CreateChainmakerYml(String chainId,String orgId,String parPath,String nodePath,String targetPath){
        String signKey = "../config/" + parPath + "/certs/node/" + nodePath + "/" + nodePath + ".sign.key";
        String singCrt = "../config/" + parPath + "/certs/node/"+nodePath+"/"+nodePath+".sign.crt";
        try {
            // 读取现有的YAML文件内容
            Yaml yaml = new Yaml();
            Map<String, Object> yamlData = yaml.load(ClassLoader.getSystemResourceAsStream("chainPackage/config/chainmaker.yml"));
            // 修改指定内容
            Map<String, Object> log = (Map<String, Object>) yamlData.get("log");
            log.put("config_file","../config/"+parPath+"/log.yml");

            List blockchainList = new ArrayList<>();
            Map blockchainMap = new LinkedHashMap();
            blockchainMap.put("chainId",chainId);
            blockchainMap.put("genesis","../config/"+parPath+"/chainconfig/bc1.yml");
            blockchainList.add(blockchainMap);
            yamlData.put("blockchain",blockchainList);

            Map<String, Object> node = (Map<String, Object>) yamlData.get("node");
            node.put("org_id",orgId);
            node.put("priv_key_file",signKey);
            node.put("cert_file",singCrt);

            Map<String, Object> net = (Map<String, Object>) yamlData.get("net");
            Record record = Db.findFirst("SELECT * FROM cmb_chain_org_node WHERE org_id=?", orgId);
            net.put("listen_addr","/ip4/0.0.0.0/tcp/"+record.getStr("node_p2p_port"));
            List nodeList = new ArrayList<>();
            List<Record> seedList = Db.find("SELECT * FROM cmb_chain_org_node WHERE chain_id=? and org_id !=''", chainId);
            for (Record seed:seedList) {
                nodeList.add("/ip4/"+seed.getStr("node_ip")+"/tcp/"+seed.getStr("node_p2p_port")+"/p2p/"+seed.getStr("node_id"));
            }
            net.put("seeds",nodeList);

            Map<String, Object> netTls = (Map<String, Object>) net.get("tls");
            netTls.put("priv_key_file",signKey);
            netTls.put("cert_file",singCrt);

            Map<String, Object> rpc = (Map<String, Object>) yamlData.get("rpc");
            rpc.put("port",record.getInt("node_rpc_port"));
            Map<String, Object> rpcTls = (Map<String, Object>) rpc.get("tls");
            rpcTls.put("priv_key_file",signKey);
            rpcTls.put("cert_file",singCrt);

            Map<String, Object> monitor = (Map<String, Object>) yamlData.get("monitor");
            monitor.put("port",monitorPort);
            Map<String, Object> storage = (Map<String, Object>) yamlData.get("storage");
            storage.put("store_path","../data/"+parPath+"/ledgerData1");
            Map<String, Object> blockdbConfig = (Map<String, Object>) storage.get("blockdb_config");
            Map<String, Object> leveldbConfig = (Map<String, Object>) blockdbConfig.get("leveldb_config");
            leveldbConfig.put("store_path","../data/"+parPath+"/block");
            Map<String, Object> statedbConfig = (Map<String, Object>) storage.get("statedb_config");
            Map<String, Object> leveldbConfig2 = (Map<String, Object>) statedbConfig.get("leveldb_config");
            leveldbConfig2.put("store_path","../data/"+parPath+"/state");
            Map<String, Object> historydbConfig = (Map<String, Object>) storage.get("historydb_config");
            Map<String, Object> leveldbConfig3 = (Map<String, Object>) historydbConfig.get("leveldb_config");
            leveldbConfig3.put("store_path","../data/"+parPath+"/history");
            Map<String, Object> resultdbConfig = (Map<String, Object>) storage.get("resultdb_config");
            Map<String, Object> leveldbConfig4 = (Map<String, Object>) resultdbConfig.get("leveldb_config");
            leveldbConfig4.put("store_path","../data/"+parPath+"/result");

            Map<String, Object> vm = (Map<String, Object>) yamlData.get("vm");
            Map<String, Object> go = (Map<String, Object>) vm.get("go");
            go.put("data_mount_path","../data/"+parPath+"/go");
            go.put("log_mount_path","../log/"+parPath+"/go");

            // 设置DumperOptions以保留注释和层级结构
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); // 保留层级结构
            options.setPrettyFlow(true); // 保留注释和布局
            options.setAllowReadOnlyProperties(true); // 保留注释
            // 创建一个新的YAML文件，并将修改后的内容写入其中，保留注释和层级结构
            FileWriter writer = new FileWriter(targetPath+"/chainmaker.yml");
            Yaml yamlWithCommentsAndHierarchy = new Yaml(options);
            yamlWithCommentsAndHierarchy.dump(yamlData, writer);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    /**
     * 创建bc1.yml文件
     * */
    public static void CreateBcYml(String chainId,String orgId,String parPath,String targetPath){
        try {
            // 读取现有的YAML文件内容
            Yaml yaml = new Yaml();
            Map<String, Object> yamlData = yaml.load(ClassLoader.getSystemResourceAsStream("chainPackage/config/chainconfig/bc1.yml"));
            // 修改指定内容
            yamlData.put("chain_id",chainId);

            Map<String, Object> consensus = (Map<String, Object>) yamlData.get("consensus");
            List nodeList = new ArrayList<>();
            List trustList = new ArrayList<>();
            List<Record> records = Db.find("SELECT * FROM cmb_chain_org_node WHERE chain_id= ? and org_id !=''",chainId);
            for (Record record:records) {
                Map nodeMap = new LinkedHashMap();
                List nodeList1 = new ArrayList<>();
                nodeList1.add(record.getStr("node_id"));
                nodeMap.put("org_id",record.getStr("org_id"));
                nodeMap.put("node_id",nodeList1);
                nodeList.add(nodeMap);
                //新建ca.crt证书
                Record certRecord = Db.findFirst("SELECT * FROM cmb_cert WHERE cert_type='1' and org_id=?", record.getStr("org_id"));
                if(certRecord!=null){
                    List nodeList2 = new ArrayList<>();
                    nodeList2.add("../config/"+parPath+"/certs/ca/"+certRecord.getStr("org_id")+"/ca.crt");
                    Map trustMap = new LinkedHashMap();
                    trustMap.put("org_id",certRecord.getStr("org_id"));
                    trustMap.put("root",nodeList2);
                    trustList.add(trustMap);
                }

            }
            consensus.put("nodes",nodeList);
            yamlData.put("trust_roots",trustList);



            // 设置DumperOptions以保留注释和层级结构
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); // 保留层级结构
            options.setPrettyFlow(true); // 保留注释和布局
            options.setAllowReadOnlyProperties(true); // 保留注释
            // 创建一个新的YAML文件，并将修改后的内容写入其中，保留注释和层级结构
            FileWriter writer = new FileWriter(targetPath+"/bc1.yml");
            Yaml yamlWithCommentsAndHierarchy = new Yaml(options);
            yamlWithCommentsAndHierarchy.dump(yamlData, writer);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
